package bancosys.tec.services.validation.base;

import java.util.LinkedList;
import java.util.List;

import jmine.tec.services.ServicesController;
import jmine.tec.services.api.Service;
import jmine.tec.services.api.ServiceAssertionFailedError;
import jmine.tec.services.api.ServicesAPIMessages;
import jmine.tec.services.api.ServicesPage;
import jmine.tec.services.api.validation.ServicesPageValidator;
import bancosys.tec.persist.PersistenceController;

/**
 * Validator responsável por validar se todos os parametros exigidos pelos serviços foram passados.
 * 
 * @author Rafael Volpato
 */
public class MissingServicesParamsValidador implements ServicesPageValidator {

    private ServicesController servicesController;

    private PersistenceController persistenceController;

    /**
     * Valida se todos os parametros obrigatórios dos serviços foram informados.
     * 
     * @param servicesPages lista de páginas de serviços.
     * @return uma lista com mensagens de erros.
     */
    public List<String> validate(List<ServicesPage> servicesPages) {
        List<String> errors = new LinkedList<String>();

        try {
            this.persistenceController.startTransaction();
            for (ServicesPage servicesPage : servicesPages) {
                errors.addAll(this.doValidateServicesPage(servicesPage));
            }
        } finally {
            this.persistenceController.rollback();
        }

        return errors;
    }

    /**
     * Valida se todos os servicos estao consistentes (possuem todas as informacoes necessarias).
     * 
     * @param servicesPage pagina de servicos
     * @return uma lista com todos os erros encontrados nos servicos
     */
    private List<String> doValidateServicesPage(ServicesPage servicesPage) {
        LinkedList<String> errosValidacao = new LinkedList<String>();

        for (Service<?> service : servicesPage.getServices()) {
            List<String> errors = service.validate();
            if (errors != null && !errors.isEmpty()) {
                String serviceDescr = service.toString();
                for (String erro : errors) {
                    String msg = serviceDescr + " " + erro;
                    this.servicesController.fireServiceFailure(service, new ServiceAssertionFailedError(
                            ServicesAPIMessages.VALIDATION_VALIDATION_ERROR.create(msg)));
                    errosValidacao.add(msg);
                }
            }
        }

        return errosValidacao;
    }

    /**
     * @param servicesController the servicesController to set
     */
    public void setServicesController(ServicesController servicesController) {
        this.servicesController = servicesController;
    }

    /**
     * @param controller the persistenceController to set
     */
    public void setPersistenceController(PersistenceController controller) {
        this.persistenceController = controller;
    }
}
